TITL DAI FIRMWARE 1EE0B-1EFFF V1.0 Rev.1 ORG :EE0B * * * ************** * (not used) * ************** * L1E245 PUSH H CALL :D891 * *********************************************** * LOADA: READ ARRAY DATA FROM TAPE INTO ARRAY * *********************************************** * * Reads block(s) from tape into the free RAM space * and move it afterwards into the array. * * Entry: HL: Length of name requested. * A: Variable type. * On stack: Address where to dump data. * L1E273 PUSH B PUSH PSW Save var.type LXI B,:3200 File type in B, C for load REM during program CALL :D681 Open read file POP H Get var.type in H CALL :EFB5 Read var.type from tape CMP H Correct type ? JNZ :DA1A Run error 'TYPE MISMATCH' REM if not CPI :20 JZ :EE38 Jump if string arrays REM * If INT/FPT arrays: REM POP H XTHL Get dumpaddr in HL XCHG Get length in HL DAD D HL is end dump area XCHG in DE; HL is start dump CALL :02D1 Read block from tape JNC :D2B3 Evt run 'LOADING ERROR ..' L1E246 CALL :02D4 Stop reading LDA :0040 Get POROM JMP :EFA6 Select ROM bank 0, abort REM * If string arrays: REM L1E247 PUSH D LHLD :02A5 Get bottom screen RAM XCHG in DE LHLD :02A3 Get begin free RAM space PUSH H CALL :D897 Read block from tape into REM free RAM area; evt.run error POP H Get begin free RAM MOV D,M ) INX H ) Length of array in DE MOV E,M ) INX H JMP :D6E5 Via D6E5 to 1EE4C * L1E248 PUSH B Save length array PUSH D CALL :CBA8 Erase stringreference REM in heap and symtab DCX H DCX H POP D PUSH H LDAX D CALL :D18B Get place in heap for string PUSH H CALL :D172 Transfer string into heap POP B POP H ) MOV M,C ) Length into heap at INX H ) begin of string MOV M,B ) INX H POP B Get length array DCX B ) Update it DCX B ) MOV A,B ORA C JNZ :EE4C Next string if not ready JMP :EE2F Stop reading, select ROM REM bank 0; abort * * * ============ *** SOUND MODULE *** * ============ * * TEMPO MVI C,:00 Count SCB LXI H,:01C2 Addr sound control block 0 L1E250 PUSH H Preserve addr SCB MOV A,M Get value of volume counter CPI :FE JZ :EE7E If FE: No increment (sound REM forever) JNC :EF9D If FF: Goto next block REM (sound off) INR M ) Incr duration count volume L1E251 INR A ) PUSH H Preserve addr SCB MOV B,A Save incr duration count INX H MOV E,M ) Get pntr envelope count INX H ) in DE MOV D,M ) LDAX D Get envelope duration count CMP B Comp with volume count JNC :EEB8 Jump if env. not counted out REM * Envelope counted out: REM XCHG XTHL Addr env.duration on stack; REM addr SCB in HL MVI M,:00 Present duration count is 0 POP H Get pntr to env.table INX H +1 MOV A,M Get next env. duration ORA A Is it FF ? CM :EF93 Then restart envelope MOV B,A Env duration in B INX H Pnts to next pos env table MOV A,M Value in A XCHG MOV M,D ) Set env pointer in SCB DCX H ) to new time field MOV M,E ) INX H INX H INX H INX H HL pnts to vol.multiplier PUSH H MOV L,M Sound volume *8 in L MVI H,:00 DAD H *16 in HL XCHG Multiplier in DE LXI H,:0080 Init.value L1E252 DCR B Decr. envelope duration JM :EEB1 Jump if ready DAD D Add multiplier JMP :EEA9 Again L1E253 MOV B,H New eff. volume in B POP H INX H MOV M,B Set new basic volume JMP :EEBD REM * If envelope not counted out: REM L1E254 POP D INX H INX H INX H INX H REM * Handle tremolo: REM L1E255 MOV B,M Get basic volume in B INX H MOV A,M Get tremolo count ORA A JZ :EEEB Jump if no tremolo adj. ADI :01 ) ACI :00 ) Incr tremolo count MOV M,A ) RAR RAR RAR JNC :EEDC No adj. if bit 2 of REM is 0 INR B ) INR B ) Else add 4 units to INR B ) basic volume INR B ) RAR NOP JC :EEDC No adjust if bit 2 of REM = 0 MOV A,B SUI :08 Else: basic vol. -2 units MOV B,A * L1E256 NOP MOV A,B Get updated basic volume MVI B,:00 ORA A JM :EEEB Jump if B1-FF MVI B,:0F CMP B JNC :EEEB Jump if >=0F (max.value) MOV B,A * L1E257 INX H Pnts to actual volume MOV A,B Get new basic volume SUB M Minus actual volume RLC ) RAR ) CMC ) New actual volume is ACI :00 ) old one + 0.5 RLC ) (difference +/- 1) RAR ) RAR ) ADD M ) MOV M,A Store in SCB MOV B,A and in B PUSH H PUSH B LXI D,:0294 Addr POROM LXI H,:FD04 Addr PORO MOV A,C Get SCB count MVI C,:F0 Mask for vol. SCB0,SCB2 RRC JNC :EF12 Jump if SCB0,SCB2 MVI C,:0F Mask for vol. SCB1,NCB PUSH PSW MOV A,B ) ADD A ) Actual volume into ADD A ) hinibble for SCB1 ADD A ) and NCB ADD A ) MOV B,A ) POP PSW L1E258 RAR JNC :EF18 Jump if SCB0,SCB1 INX D ) POR0M+1,POR0+1 INX H ) for SCB2,NCB L1E259 LDAX D Get POR0M,POR1M ANA C Only reqd volume ORA B Update it STAX D Back in POR0M,POR1M MOV M,A and in POR0,POR1 POP B POP H INR C SCB count +1 MOV A,C CPI :04 JZ :EFA4 Ready if block was NCB REM REM REM INX H MOV A,M Get glissando flag DCR A JM :EF8B Ready if end period REM reached INX H MOV E,M ) Get current period of INX H ) output in DE MOV D,M ) PUSH H INX H MOV A,M ) Get reqd final period INX H ) in HL MOV H,M ) MOV L,A JNZ :EF3B Jump if end period not REM reached MOV D,H ) HL=DE if 'set freq' MOV E,L ) L1E260 CALL :DE14 Compare HL-DE PUSH PSW PUSH D JNC :EF44 Jump if final period >= REM current period XCHG Else exchange values L1E261 CALL :DE1A Calc difference in HL POP D PUSH D PUSH H XCHG MVI E,:40 ) L1E262 MOV A,L ) RAL ) MOV L,A ) MOV A,H ) RAL ) HL = HL SHL 6 MOV H,A ) MOV A,E ) RAL ) MOV E,A ) JNC :EF4D MOV L,H ) HL = 1/64 orig. value MOV H,E ) MOV A,H ORA L JNZ :EF61 INX H L1E263 POP D CALL :DE14 Compare HL-DE MVI B,:02 JC :EF6D Jump if DE > HL MVI B,:00 XCHG L1E264 POP D POP PSW JNC :EF75 CALL :DE26 HL is its 2-compl. L1E265 DAD D XCHG POP H MOV M,D ) Set new current period DCX H ) MOV M,E ) DCX H MOV M,B Set glissando flag PUSH B MOV A,C ) DCR A ) Calc offset for oscill. ADD A ) address MOV C,A ) MVI B,:00 LXI H,:FC00 Addr osc. channel 0 DAD B HL = addr current osc MOV M,E ) Load oscillator MOV M,D ) POP B REM * Block done: REM L1E266 LXI D,:000E POP H Get startadr prev. block DAD D HL pnts to next block JMP :EE73 Run next block * * RESTART ENVELOPE: * * Gets 1st volume of envelope. * * Entry: DE: Points to 2nd byte of envelope pointer * of a SCB. * Exit: A: Volume. * HL: Address volume field in envelope. * BCDEF preserved. * L1E267 PUSH D Save pntr INX D LDAX D Get lobyte env pntr MOV L,A in L INX D LDAX D Get hibyte env pntr MOV H,A in H POP D Restore pntr MOV A,M Get volume in A RET * * IF SOUND OF BLOCK IS 'OFF': GOTO NEXT BLOCK: * L1E268 INR C Update SCB count MOV A,C CPI :04 All blocks done ? JNZ :EF8B Next block if not L1E269 POP H RET * *************** * BANK RETURN * *************** * * Goto ROM bank 0. * * Entry: A: Current POROM. * BRET POP B ANI :3F Select ROM bank 0 JMP :D808 Load PORO/POROM * DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF * *************************************** * LOADA: READ VARIABLE TYPE FROM TAPE * *************************************** * * Reads 1 byte from tape. * * Exit: A: Variable type. * DEHL preserved. * R1BB PUSH H PUSH D LXI H,:013E Startaddr EBUF LXI D,:013F Next addr CALL :02D1 Read type from tape JNC :D2B3 Evt run 'LOADING ERROR ..' LDA :013E Get var.type in A POP D POP H RET * DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF DATA :FF * ************************* * part of 'EXP' (1E667) * ************************* * L1E272 ORA H JP :E6B8 JMP :E6AD * * * END